package dsx.msg;

import dsx.log.DsxLog;
import dsx.log.ServLog;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class MsgHandlerSet {

    private _MsgHandlerSetConf conf;
    private ConcurrentHashMap<Integer, _MsgType> msgTypeMap;
    private ConcurrentHashMap<Integer, IMsgHandler> handlerMap;

    public ArrayList<_MsgType> getMsgTypes() {
        ArrayList<_MsgType> msgTypes = new ArrayList<>();
        for (Map.Entry<Integer, _MsgType> entry: msgTypeMap.entrySet()) {
            msgTypes.add(entry.getValue());
        }
        return msgTypes;
    }

    public MsgHandlerSet(_MsgHandlerSetConf conf) {
        this.conf = conf;
        this.msgTypeMap = new ConcurrentHashMap<>();
        this.handlerMap = new ConcurrentHashMap<>();
        this.loadMsgTypes();
    }

    public boolean handleMsg(_Msg msg) {
        try {
            if (!handlerMap.containsKey(msg.code)) {
                if (!msgTypeMap.containsKey(msg.code))
                    return false;
                _MsgType msgType = msgTypeMap.get(msg.code);
                IMsgHandler msgHandler = (IMsgHandler) Class.forName(msgType.getHandleClass()).newInstance();
                handlerMap.put(msg.code, msgHandler);
            }
            return handlerMap.get(msg.code).handle(msg.getParam());
        } catch (Exception ex) {
            return false;
        }
    }

    private void loadMsgTypes() {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document document = db.parse(new File(conf.path));
            Element root = document.getDocumentElement();
            NodeList msgTypes = root.getElementsByTagName("MsgType");
            int msgTypeNum = msgTypes.getLength();
            NodeList tmp;
            for (int i = 0; i < msgTypeNum; i++) {
                _MsgType msgType = new _MsgType();
                tmp = ((Element) msgTypes.item(i)).getElementsByTagName("code");
                if (tmp.getLength() > 0)
                    msgType.setCode(Integer.parseInt(tmp.item(0).getTextContent()));
                tmp = ((Element) msgTypes.item(i)).getElementsByTagName("desc");
                if (tmp.getLength() > 0)
                    msgType.setDesc(tmp.item(0).getTextContent());
                tmp = ((Element) msgTypes.item(i)).getElementsByTagName("class");
                if (tmp.getLength() > 0)
                    msgType.setHandleClass(tmp.item(0).getTextContent());
                tmp = ((Element) msgTypes.item(i)).getElementsByTagName("maxHandlingNum");
                if (tmp.getLength() > 0)
                    msgType.setMaxHandlingNum(Integer.parseInt(tmp.item(0).getTextContent()));
                else
                    msgType.setMaxHandlingNum(0);
                this.msgTypeMap.put(msgType.code, msgType);
            }
        } catch (Exception ex) {
            DsxLog.writeLog(ex.getMessage(), "msgQueueError", "", ServLog.error);
        }
    }

}
